using System.Windows.Forms;

namespace WowAceUpdater
{
    internal abstract class TextInvoker
    {
        private Control _invoker;

        protected TextInvoker()
        {
        }

        protected TextInvoker(Control c)
        {
            _invoker = c;
        }

        protected abstract string InstanceText { get; set; }

        protected Control Invoker
        {
            get { return _invoker; }
            set { _invoker = value; }
        }

        public string Text
        {
            get { return InstanceText; }
            set { SetTextCore(value); }
        }

        protected void SetTextCore(string value)
        {
            if (null != Invoker && Invoker.InvokeRequired)
            {
                SetTextCallback setText = SetTextCore;
                Invoker.BeginInvoke(setText, new object[] {value});
            }
            else
            {
                if (Invoker.IsDisposed)
                    return;

                InstanceText = value;
            }
        }


        public static TextInvoker GetInvoker(ToolStripItem obj)
        {
            return new TextInvokerTS<ToolStripItem>(obj);
        }

        public static TextInvoker GetInvoker(Control obj)
        {
            return new TextInvokerC<Control>(obj);
        }

        #region Nested type: SetTextCallback

        private delegate void SetTextCallback(string text);

        #endregion
    }


    internal class TextInvokerC<T> : TextInvoker where T : Control
    {
        private readonly T _instance;

        public TextInvokerC(T src) : base(src)
        {
            _instance = src;
        }

        protected override string InstanceText
        {
            get { return _instance.Text; }
            set { _instance.Text = value; }
        }
    }

    internal class TextInvokerTS<T> : TextInvoker where T : ToolStripItem
    {
        private readonly T _instance;

        public TextInvokerTS(T src) : base(src.GetCurrentParent())
        {
            _instance = src;
        }

        protected override string InstanceText
        {
            get { return _instance.Text; }
            set { _instance.Text = value; }
        }
    }
}